package com.bobo.web.provider.controller;

import com.bobo.web.api.constants.RedisConstant;
import com.bobo.web.api.domain.order.InsuranceDO;
import com.bobo.web.api.domain.order.InsuranceSeckill;
import com.bobo.web.api.vo.base.ResponseResult;
import com.bobo.web.api.vo.order.CreateSecKillParam;
import com.bobo.web.provider.service.order.InsuranceOrderService;
import com.bobo.web.provider.service.order.InsuranceService;
import com.bobo.web.provider.util.JedisUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

import static java.util.concurrent.Executors.newFixedThreadPool;

@RestController
@RequestMapping("api/order")
public class OrderController {
    @Resource
    private InsuranceService insuranceService;
    @Resource
    private InsuranceOrderService insuranceOrderService;
    @Resource
    private JedisUtils jedisUtils;
    private static Logger LOGGER = LoggerFactory.getLogger(OrderController.class);

    /**
     * 获取险种详情
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getInsurance", method = {RequestMethod.GET})
    public ResponseResult<InsuranceDO> getInsurance(@RequestParam("id") Long id) {
        InsuranceDO insurance = insuranceService.getInsurance(id);
        return ResponseResult.success(insurance);

    }

    /**
     * 获取险种秒杀相关的信息
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getSeckillInsuranceDetail", method = {RequestMethod.GET})
    public ResponseResult<InsuranceSeckill> getSeckillInsuranceDetail(@RequestParam("id") Long id) {
        List<InsuranceSeckill> seckillInsuranceList = insuranceService.getSeckillInsuranceByID(id);
        if (CollectionUtils.isEmpty(seckillInsuranceList)) {
            return ResponseResult.success(null);
        }
        jedisUtils.hset(RedisConstant.INSURANCE_SEC_KILL+id,"st", String.valueOf(seckillInsuranceList.get(0).getSeckillStartTime().getTime()));
        jedisUtils.hset(RedisConstant.INSURANCE_SEC_KILL+id,"et", String.valueOf(seckillInsuranceList.get(0).getSeckillEndTime().getTime()));
        jedisUtils.hset(RedisConstant.INSURANCE_SEC_KILL+id,"price", String.valueOf(seckillInsuranceList.get(0).getSeckillPrice()));
        Integer seckillCount = seckillInsuranceList.get(0).getSeckillCount();
        String[] value = new String[seckillCount];
        for (int i = 0; i < seckillInsuranceList.get(0).getSeckillCount(); i++) {
            value[i]= String.valueOf(i);
        }
        jedisUtils.lPush(RedisConstant.INSURANCE_SEC_KILL_COUNT+id,value);
        return ResponseResult.success(seckillInsuranceList.get(0));
    }

    /**
     * 使用数据库乐观锁实现
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "creatOrder", method = {RequestMethod.POST})
    public ResponseResult<String> creatOrder(@RequestBody CreateSecKillParam createSecKillParam) {
        if (createSecKillParam.getInsuranceId() == null || StringUtils.isBlank(createSecKillParam.getUserId())) {
            return ResponseResult.error("参数不全");
        }
        createSecKillParam.setUserId("yangbo" + RandomUtils.nextInt(100, 2002));
        try {
            insuranceOrderService.createInsuranceOrder(createSecKillParam);
//            LOGGER.info(String.format("用户%s抢购成功", createSecKillParam.getUserId()));
        } catch (Exception e) {
//            LOGGER.info(String.format("用户%s抢购失败", createSecKillParam.getUserId()));
        }
        return ResponseResult.success("OK");
    }

    /**
     * 获取险种秒杀相关的信息
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "creatOrderReturn", method = {RequestMethod.POST})
    public ResponseResult<String> creatOrderReturn(@RequestBody CreateSecKillParam createSecKillParam) throws ExecutionException, InterruptedException {
        if (createSecKillParam.getInsuranceId() == null || StringUtils.isBlank(createSecKillParam.getUserId())) {
            return ResponseResult.error("参数不全");
        }
        List<Future> futureList = new ArrayList<Future>();
        ExecutorService executorService = newFixedThreadPool(100);
        CountDownLatch countDownLatch = new CountDownLatch(Math.toIntExact(createSecKillParam.getRequestNum()));
        long startTime = System.currentTimeMillis();
        LOGGER.info("抢购开始。。。。。");
        for (int i = 0; i < createSecKillParam.getRequestNum(); i++) {
            futureList.add(executorService.submit(new Callable() {
                @Override
                public Object call() throws Exception {
                    createSecKillParam.setUserId("yangbo" + RandomUtils.nextInt(100, 2002));
                    try {
                        insuranceOrderService.createInsuranceOrder(createSecKillParam);
                        countDownLatch.countDown();
                        return 1;
                    } catch (Exception e) {
                        countDownLatch.countDown();
                        LOGGER.info(String.format("用户%s抢购失败", createSecKillParam.getUserId()));
                        return 0;
                    }
                }
            }));
        }
        while (countDownLatch.getCount() > 0) {

            long endTime = System.currentTimeMillis();
            LOGGER.info("抢购结束。。。");
            int succ = 0;
            int fail = 0;
            for (Future future : futureList) {
                Integer o = (Integer) future.get();
                if (o == 1) {
                    succ++;
                } else {
                    fail++;
                }
            }
            LOGGER.info(String.format("抢购成功=%s,抢购失败=%s", succ, fail));
        }
        return ResponseResult.success("OK");
    }
}
